package com.kingdee.eas.hr.affair.app;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.eas.basedata.org.AdminOrgUnitFactory;
import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
import com.kingdee.eas.basedata.org.IAdminOrgUnit;
import com.kingdee.eas.basedata.org.IPosition;
import com.kingdee.eas.basedata.org.PositionFactory;
import com.kingdee.eas.basedata.org.PositionInfo;
import com.kingdee.eas.basedata.person.IPerson;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.eas.hr.affair.FluctuationBizBillEntryCollection;
import com.kingdee.eas.hr.affair.FluctuationBizBillEntryFactory;
import com.kingdee.eas.hr.affair.FluctuationBizBillEntryInfo;
import com.kingdee.eas.hr.affair.FluctuationBizBillFactory;
import com.kingdee.eas.hr.affair.FluctuationBizBillInfo;
import com.kingdee.eas.hr.affair.HRAffairBizBillEntryInfo;
import com.kingdee.eas.hr.affair.SecEntryCollection;
import com.kingdee.eas.hr.affair.SecEntryFactory;
import com.kingdee.eas.hr.affair.SecEntryInfo;
import com.kingdee.eas.hr.emp.PersonPositionCollection;
import com.kingdee.eas.hr.emp.PersonPositionFactory;
import com.kingdee.eas.hr.emp.PersonPositionInfo;
import com.kingdee.eas.hr.org.IJobGrade;
import com.kingdee.eas.hr.org.JobGradeFactory;
import com.kingdee.eas.hr.org.JobGradeInfo;
import com.kingdee.eas.hr.tools.AdjustSalaryTools;
import com.kingdee.eas.util.app.ContextUtil;
import com.kingdee.shr.compensation.CmpItemFactory;
import com.kingdee.shr.compensation.CmpItemInfo;
import com.kingdee.shr.compensation.FixAdjustSalaryFactory;
import com.kingdee.shr.compensation.ICmpItem;
import com.kingdee.shr.compensation.IFixAdjustSalary;
import com.kingdee.shr.costbudget.AdjustSalaryBillEntryCollection;
import com.kingdee.shr.costbudget.AdjustSalaryBillEntryInfo;
import com.kingdee.shr.costbudget.AdjustSalaryBillFactory;
import com.kingdee.shr.costbudget.AdjustSalaryBillInfo;
import com.kingdee.shr.costbudget.CmpStandardFactory;
import com.kingdee.shr.costbudget.CmpStandardInfo;
import com.kingdee.shr.costbudget.CmpStdLevelFactory;
import com.kingdee.shr.costbudget.CmpStdLevelInfo;
import com.kingdee.shr.costbudget.CmpStdPointFactory;
import com.kingdee.shr.costbudget.CmpStdPointInfo;
import com.kingdee.shr.costbudget.IAdjustSalaryBill;
import com.kingdee.shr.costbudget.ICmpStandard;
import com.kingdee.shr.costbudget.ICmpStdLevel;
import com.kingdee.shr.costbudget.ICmpStdPoint;
import com.kingdee.util.DateTimeUtils;
import com.kingdee.util.NumericExceptionSubItem;
import com.kingdee.util.StringUtils;

/**
 * @Copyright 天津金蝶软件有限公司 <br>
 *            Title: FluctuationBizBillControllerBeanEx <br>
 *            Description: 调动单扩展类
 * @author yacong_liu Email:yacong_liu@kingdee.com
 * @date 2018-12-21 & 下午06:39:21
 * @since V1.0
 */
public class FluctuationBizBillControllerBeanEx extends FluctuationBizBillControllerBean {

    private ICmpStandard iCmpStandard = null;

    private ICmpStdLevel iCmpStdLevel = null;

    private ICmpStdPoint iCmpStdPoint = null;

    private ICmpItem iCmpItem = null;

    private IAdminOrgUnit iAdminOrgUnit = null;

    private IPosition iPosition = null;

    private IJobGrade iJobGrade = null;

    /**
     * （非 Javadoc）
     * <p>
     * Title: _doWithCommonRelationEffect
     * </p>
     * <p>
     * Description: 提交生效以及提交工作流审批通过 会走此方法
     * </p>
     * 
     * @param ctx
     * @param entry
     * @throws BOSException
     * @throws EASBizException
     * @see com.kingdee.eas.hr.affair.app.FluctuationBizBillControllerBean#_doWithCommonRelationEffect(com.kingdee.bos.Context,
     *      com.kingdee.eas.hr.affair.HRAffairBizBillEntryInfo)
     */
    @Override
    protected void _doWithCommonRelationEffect(Context ctx, HRAffairBizBillEntryInfo entry)
            throws BOSException, EASBizException {
        // 同步定调薪单数据及薪酬机构记录
        super._doWithCommonRelationEffect(ctx, entry);

        FluctuationBizBillEntryInfo empEntry = (FluctuationBizBillEntryInfo) entry;
        /*
         * @update 2018-12-26 调岗不调薪 经PM确认，当默认薪酬标准无值时 视为 只调岗不调薪 不同步数据
         */
        CmpStandardInfo entryCmpStandard = (CmpStandardInfo) empEntry.get("cmpStandard");
        if (entryCmpStandard != null) {
            System.out.println("调动单已触发开始同步定调薪单数据。");

            FluctuationBizBillInfo bill = empEntry.getBill();
            saveAdjustSalaryBill(ctx, bill);

            System.out.println("调动单同步定调薪单数据完成。");
        }

    }

    /**
     * （非 Javadoc）
     * <p>
     * Title: _untiCheckBizBill
     * </p>
     * <p>
     * Description: 反审批
     * </p>
     * 
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     * @see com.kingdee.eas.hr.affair.app.HRAffairBizBillControllerBean#_untiCheckBizBill(com.kingdee.bos.Context,
     *      java.lang.String)
     */
    @Override
    protected void _untiCheckBizBill(Context ctx, String billId) throws BOSException, EASBizException {

        // 撤回同步的定调薪单及薪酬结构记录 撤回的规则是 人员 和 生效日期
        FluctuationBizBillInfo bill = FluctuationBizBillFactory.getLocalInstance(ctx)
                .getFluctuationBizBillInfo(new ObjectUuidPK(billId));
        // 入职申请日期
        Date applyDate = bill.getApplyDate();
        FluctuationBizBillEntryCollection entrys = bill.getEntrys();
        Iterator entryIterator = entrys.iterator();
        while (entryIterator.hasNext()) {
            FluctuationBizBillEntryInfo entry = (FluctuationBizBillEntryInfo) entryIterator.next();
            FluctuationBizBillEntryInfo entryInfo = FluctuationBizBillEntryFactory.getLocalInstance(ctx)
                    .getFluctuationBizBillEntryInfo(new ObjectUuidPK(entry.getId().toString()));

            String personId = entryInfo.getPerson().getId().toString();
            System.out.println("撤回定调薪单及薪酬结构记录：personid= '" + personId + "' applyDate = '" + applyDate + "'");

            revokeAdjustSalaryBill(ctx, personId, applyDate);

        }

        super._untiCheckBizBill(ctx, billId);
    }

    /**
     * 
     * <p>
     * Title: saveAdjustSalaryBill
     * </p>
     * <p>
     * Description: 同步定调薪单及薪酬结构记录
     * </p>
     * 
     * @param ctx
     * @param bill
     * @throws BOSException
     * @throws EASBizException
     */
    @SuppressWarnings("unchecked")
    private void saveAdjustSalaryBill(Context ctx, FluctuationBizBillInfo info) throws EASBizException,
            BOSException {

        FluctuationBizBillEntryInfo entryInfo = info.getEntrys().get(0);
        String id = entryInfo.getId().toString();
        if (StringUtils.isEmpty(id)) {
            return;
        }
        /*
         * @description 只有入职单入职生效日期是当天时，入职人员才会分配Id。经与PM确认，从业务角度限定只能是当天入职。
         */
        PersonInfo person = entryInfo.getPerson();
        if (person == null) {
            return;
        }
        String personIdStr = person.getId().toString();

        PersonInfo personInfo = getPersonInfo(ctx, personIdStr);
        if (personInfo == null) {
            return;
        }

        // DEP 给 调动单分录增加 默认薪酬标准
        CmpStandardInfo entryCmpStandard = (CmpStandardInfo) entryInfo.get("cmpStandard");
        CmpStandardInfo entryCmpStandardInfo = null;
        if (entryCmpStandard != null) {
            entryCmpStandardInfo = getCmpStandardInfo(ctx, entryCmpStandard.getId().toString());
        }

        /*
         * 定调薪单初始化信息
         */
        Date nowDate = DateTimeUtils.truncateDate(new Date());
        UserInfo currentUserInfo = ContextUtil.getCurrentUserInfo(ctx);

        PersonPositionInfo personPositionInfo = getAdminOrgUnit(ctx, personIdStr);

        // 根据人员获取定调薪单上的人员信息
        AdjustSalaryBillInfo asInfo = new AdjustSalaryBillInfo();
        SecEntryCollection SecEntry = info.getSecentry();
        AdjustSalaryBillEntryCollection aseColl = new AdjustSalaryBillEntryCollection();

        Map<String, Object> adjustPersonInfo = AdjustSalaryTools.getPersonOtherInfo(ctx, personIdStr);
        if (adjustPersonInfo != null) {
            AdminOrgUnitInfo nowOrgInfo = null;
            PositionInfo nowPositionInfo = null;
            JobGradeInfo nowJobGradeInfo = null;
            // 现组织
            if (adjustPersonInfo.containsKey("NowOrg")) {
                HashMap<String, String> nowOrg = (HashMap<String, String>) adjustPersonInfo.get("NowOrg");

                nowOrgInfo = getAdminOrgUnitInfo(ctx, nowOrg.get("id"));
            }

            // 现职位
            if (adjustPersonInfo.containsKey("NowPosition")) {
                HashMap<String, String> nowPosition = (HashMap<String, String>) adjustPersonInfo
                        .get("NowPosition");

                nowPositionInfo = getPositionInfo(ctx, nowPosition.get("id"));
            }

            // 现职等
            if (adjustPersonInfo.containsKey("NowJobGrade")) {
                HashMap<String, String> nowJobGrade = (HashMap<String, String>) adjustPersonInfo
                        .get("NowJobGrade");
                nowJobGradeInfo = getJobGradeInfo(ctx, nowJobGrade.get("id"));
            }

            if (personInfo != null) {
                asInfo.setPerson(personInfo);
            }
            if (nowOrgInfo != null) {
                asInfo.setNowOrg(nowOrgInfo);
            }

            if (nowPositionInfo != null) {
                asInfo.setNowPosition(nowPositionInfo);
            }
            if (nowJobGradeInfo != null) {
                asInfo.setNowJobGrade(nowJobGradeInfo);
            }

            // 默认薪酬标准
            if (entryCmpStandardInfo != null) {
                asInfo.setCmpStandard(entryCmpStandardInfo);
            }
            // 制单人
            asInfo.setProposer(currentUserInfo.getPerson());
            // 制单日期
            asInfo.setApplyDate(nowDate);
            // 所属行政组织
            asInfo.setAdminOrg(personPositionInfo.getPersonDep());
            asInfo.setIsMultiEntry(true);

        }

        for (int i = 0; i < SecEntry.size(); i++) {

            SecEntryInfo sei = SecEntry.get(i);
            SecEntryInfo secEntryInfo = SecEntryFactory.getLocalInstance(ctx).getSecEntryInfo(
                    new ObjectUuidPK(sei.getId().toString()));

            AdjustSalaryBillEntryInfo asbeInfo = new AdjustSalaryBillEntryInfo();

            // 原薪酬标准
            CmpStandardInfo oldCmpStandard = secEntryInfo.getOldCmpStandard();
            if (oldCmpStandard != null) {
                CmpStandardInfo oldCmpStandardInfo = getCmpStandardInfo(ctx, oldCmpStandard.getId()
                        .toString());

                asbeInfo.setOldCmpStandard(oldCmpStandardInfo);
            }

            // 原薪等
            CmpStdLevelInfo oldCmpLevel = secEntryInfo.getOldCmpLevel();
            if (oldCmpLevel != null) {
                CmpStdLevelInfo oldCmpStdLevelInfo = getCmpStdLevelInfo(ctx, oldCmpLevel.getId().toString());

                asbeInfo.setOldCmpLevel(oldCmpStdLevelInfo);
            }

            // 原薪级
            CmpStdPointInfo oldStdPoint = secEntryInfo.getOldStdPoint();
            if (oldStdPoint != null) {
                CmpStdPointInfo oldCmpStdPointInfo = getCmpStdPointInfo(ctx, oldStdPoint.getId().toString());

                asbeInfo.setOldStdPoint(oldCmpStdPointInfo);
            }

            // 原值
            BigDecimal oldMoney = secEntryInfo.getOldMoney();
            asbeInfo.setOldMoney(oldMoney);

            // 现薪酬标准
            CmpStandardInfo cmpStandard = secEntryInfo.getCmpStandard();
            if (cmpStandard.getId() != null) {
                CmpStandardInfo cmpStandardInfo = getCmpStandardInfo(ctx, cmpStandard.getId().toString());

                asbeInfo.setCmpStandard(cmpStandardInfo);
            }

            // 薪酬项目
            CmpItemInfo cmpItem = secEntryInfo.getCmpItem();
            if (cmpItem.getId() != null) {
                CmpItemInfo cmpItemInfo = getCmpItemInfo(ctx, cmpItem.getId().toString());

                asbeInfo.setCmpItem(cmpItemInfo);
            }

            // 新薪等
            CmpStdLevelInfo cmpLevel = secEntryInfo.getCmpLevel();
            if (cmpLevel.getId() != null) {
                CmpStdLevelInfo cmpStdLevelInfo = getCmpStdLevelInfo(ctx, cmpLevel.getId().toString());

                asbeInfo.setCmpLevel(cmpStdLevelInfo);
            }

            // 新级
            CmpStdPointInfo stdPoint = secEntryInfo.getStdPoint();
            if (stdPoint.getId() != null) {
                CmpStdPointInfo cmpStdPointInfo = getCmpStdPointInfo(ctx, stdPoint.getId().toString());

                asbeInfo.setStdPoint(cmpStdPointInfo);
            }

            // 新值
            BigDecimal money = secEntryInfo.getMoney();
            // 生效日期
            Date effectDate = secEntryInfo.getEffectDate();

            asbeInfo.setMoney(money);
            asbeInfo.setEffectDate(effectDate);

            aseColl.add(asbeInfo);

        }
        asInfo.getEntry().addCollection(aseColl);

        // 提交生效_定调薪单（内部自动生成定薪单（薪酬结构记录））
        CoreBaseInfo coreBaseInfo = (CoreBaseInfo) asInfo;
        IAdjustSalaryBill iAdjustSalaryBill = AdjustSalaryBillFactory.getLocalInstance(ctx);
        iAdjustSalaryBill.submitEffect(coreBaseInfo);
    }

    /**
     * 
     * <p>
     * Title: revokeAdjustSalaryBill
     * </p>
     * <p>
     * Description: 撤回定调薪单及薪酬记录数据
     * </p>
     * 
     * @param ctx
     * @param personId 申请人ID
     * @param applyDate 申请日期
     * @throws BOSException
     * @throws EASBizException
     */
    private void revokeAdjustSalaryBill(Context ctx, String personId, Date applyDate) throws BOSException,
            EASBizException {

        IAdjustSalaryBill iAdjustSalaryBill = AdjustSalaryBillFactory.getLocalInstance(ctx);
        try {
            iAdjustSalaryBill.delete(" where person.id = '" + personId + "' and applyDate = {ts'" + applyDate
                    + "'}");

            revokeFixAdjustSalary(ctx, personId, applyDate);

        } catch (EASBizException e) {
            throw new EASBizException(new NumericExceptionSubItem("01", "撤回定调薪单失败！"));
        }

    }

    /**
     * 
     * <p>
     * Title: revokeFixAdjustSalary
     * </p>
     * <p>
     * Description: 撤回定薪单数据（薪酬结构记录）
     * </p>
     * 
     * @param personId 人员Id
     * @param effectDay 生效日期
     * @throws BOSException
     * @throws EASBizException
     */
    private void revokeFixAdjustSalary(Context ctx, String personId, Date effectDay) throws BOSException,
            EASBizException {

        IFixAdjustSalary iFixAdjustSalary = FixAdjustSalaryFactory.getLocalInstance(ctx);
        try {
            iFixAdjustSalary.delete(" where person.id = '" + personId + "' and effectDay = {ts'" + effectDay
                    + "'}");
        } catch (EASBizException e) {
            throw new EASBizException(new NumericExceptionSubItem("02", "撤回定薪单薪酬结构记录失败！"));
        }

    }

    private static PersonPositionInfo getAdminOrgUnit(Context ctx, String personID) {
        if (personID == null) {
            return null;
        }
        PersonPositionInfo personPositionInfo = null;
        StringBuffer oqlb = new StringBuffer();
        oqlb.append("select ");
        oqlb.append("id,");
        oqlb.append("enterDate,");
        oqlb.append("formalDate,");
        oqlb.append("jobGrade.id,");
        oqlb.append("tryoutMonth,");
        oqlb.append("jobGrade.name,");
        oqlb.append("jobLevel.id,");
        oqlb.append("jobLevel.name,");
        oqlb.append("personDep.id,");
        oqlb.append("personDep.name,");
        oqlb.append("personDep.number,");
        oqlb.append("personDep.displayName,");
        oqlb.append("primaryPosition.id,");
        oqlb.append("primaryPosition.name,");
        oqlb.append("primaryPosition.number,");
        oqlb.append("primaryPosition.job.id,");
        oqlb.append("primaryPosition.job.name");
        oqlb.append(" where person.id='");
        oqlb.append(personID);
        oqlb.append("'");
        PersonPositionCollection c = null;
        try {
            c = PersonPositionFactory.getLocalInstance(ctx).getPersonPositionCollection(oqlb.toString());
        } catch (BOSException e) {
            System.out.println("getAdminOrgUnit err" + e);
        }
        if ((c != null) && (c.size() > 0)) {
            personPositionInfo = c.get(0);
        }
        return personPositionInfo;
    }

    /**
     * 
     * <p>
     * Title: getCmpStandardInfo
     * </p>
     * <p>
     * Description: 薪酬标准
     * </p>
     * 
     * @param ctx
     * @param id 薪酬标准id
     * @return CmpStandardInfo
     * @throws EASBizException
     * @throws BOSException
     */
    private CmpStandardInfo getCmpStandardInfo(Context ctx, String id) throws EASBizException, BOSException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iCmpStandard = (iCmpStandard != null) ? iCmpStandard : CmpStandardFactory.getLocalInstance(ctx);

        return iCmpStandard.getCmpStandardInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: get
     * </p>
     * <p>
     * Description: 薪酬项目
     * </p>
     * 
     * @param ctx
     * @param id 薪酬项目id
     * @return CmpItemInfo
     * @throws BOSException
     * @throws EASBizException
     */
    private CmpItemInfo getCmpItemInfo(Context ctx, String id) throws BOSException, EASBizException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iCmpItem = (iCmpItem != null) ? iCmpItem : CmpItemFactory.getLocalInstance(ctx);

        return iCmpItem.getCmpItemInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: getCmpStdLevelInfo
     * </p>
     * <p>
     * Description: 薪等
     * </p>
     * 
     * @param ctx
     * @param id
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    private CmpStdLevelInfo getCmpStdLevelInfo(Context ctx, String id) throws BOSException, EASBizException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iCmpStdLevel = (iCmpStdLevel != null) ? iCmpStdLevel : CmpStdLevelFactory.getLocalInstance(ctx);

        return iCmpStdLevel.getCmpStdLevelInfo(new ObjectUuidPK(id));
    }

    /**
     * 
     * <p>
     * Title: getCmpStdPointInfo
     * </p>
     * <p>
     * Description: 薪级
     * </p>
     * 
     * @param ctx
     * @param id
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    private CmpStdPointInfo getCmpStdPointInfo(Context ctx, String id) throws BOSException, EASBizException {

        if (StringUtils.isEmpty(id)) {
            return null;

        }

        iCmpStdPoint = (iCmpStdPoint != null) ? iCmpStdPoint : CmpStdPointFactory.getLocalInstance(ctx);

        return iCmpStdPoint.getCmpStdPointInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: getAdminOrgUnitInfo
     * </p>
     * <p>
     * Description: 行政组织
     * </p>
     * 
     * @param ctx
     * @param id 组织id
     * @return AdminOrgUnitInfo
     * @throws EASBizException
     * @throws BOSException
     */
    private AdminOrgUnitInfo getAdminOrgUnitInfo(Context ctx, String id) throws EASBizException, BOSException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iAdminOrgUnit = (iAdminOrgUnit != null) ? iAdminOrgUnit : AdminOrgUnitFactory.getLocalInstance(ctx);

        return iAdminOrgUnit.getAdminOrgUnitInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: getPositionInfo
     * </p>
     * <p>
     * Description: 岗位
     * </p>
     * 
     * @param ctx
     * @param id 岗位id
     * @return PositionInfo
     * @throws EASBizException
     * @throws BOSException
     */
    private PositionInfo getPositionInfo(Context ctx, String id) throws EASBizException, BOSException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iPosition = (iPosition != null) ? iPosition : PositionFactory.getLocalInstance(ctx);

        return iPosition.getPositionInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: getJobGradeInfo
     * </p>
     * <p>
     * Description: 职等
     * </p>
     * 
     * @param ctx
     * @param id 职等id
     * @return JobGradeInfo
     * @throws EASBizException
     * @throws BOSException
     */
    private JobGradeInfo getJobGradeInfo(Context ctx, String id) throws EASBizException, BOSException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        iJobGrade = (iJobGrade != null) ? iJobGrade : JobGradeFactory.getLocalInstance(ctx);

        return iJobGrade.getJobGradeInfo(new ObjectUuidPK(id));

    }

    /**
     * 
     * <p>
     * Title: getPersonInfo
     * </p>
     * <p>
     * Description: 人员
     * </p>
     * 
     * @param ctx
     * @param id 人员id
     * @return PersonInfo
     * @throws EASBizException
     * @throws BOSException
     */
    private PersonInfo getPersonInfo(Context ctx, String id) throws EASBizException, BOSException {

        if (StringUtils.isEmpty(id)) {
            return null;
        }

        IPerson iPerson = PersonFactory.getLocalInstance(ctx);

        return iPerson.getPersonInfo(new ObjectUuidPK(id));

    }

}
